package com.ctgu.server.utils.oss;

import cn.hutool.Hutool;
import com.alibaba.fastjson2.util.DateUtils;
import com.alibaba.fastjson2.util.UUIDUtils;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.Date;
import java.util.UUID;

import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 阿里云OSS工具类，
 */
@Setter
@Slf4j
public class OssClientUtils {

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    private static final   String endpoint = "https://oss-cn-chengdu.aliyuncs.com";
    // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
    private static final  String accessKeyId = "LTAI5tAC1HRM1YYDfzK117x7";
    private static final  String accessKeySecret = "pcoIQvvXDMW2lAV87uwP0XK49E58IU";
    private static final String bucketName = "ctgu-qmx";

    /**
     * 创建存储桶
     */
    public void createBucket() {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 创建存储空间。
            ossClient.createBucket(bucketName);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("创建bucket失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传本地文件至OSS
     *
     * @param filePath 文件路径
     * @param key      唯一key（在oss中的文件名字）
     */
    public void upload(String filePath, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传内容到指定的存储空间（bucketName）并保存为指定的文件名称（key）。
            // String content = "Hello OSS";
            // ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            ossClient.putObject(bucketName, key, Files.newInputStream(new File(filePath).toPath()));
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传文件，以IO流方式
     *
     * @param multipartFile 输入流

     * @return url
     */
    public static String upload(MultipartFile multipartFile) {

        String url=null;
        OSS ossClient=null;
        InputStream inputStream=null;
        try {
            // 创建OSSClient实例。

            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            //获取文件流
            String fileName=multipartFile.getOriginalFilename();

            inputStream = multipartFile.getInputStream();
            assert fileName != null;

            String imgName= DateUtils.format(new Date(),"yyyy/MM/")+UUID.randomUUID()
                    +fileName.substring(fileName.lastIndexOf("."));
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, imgName, inputStream);
            putObjectRequest.setProcess("true");
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            url=result.getResponse().getUri();

        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }finally {
            // 关闭OSSClient。
            if(ossClient!=null){
                ossClient.shutdown();
            }
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return url;
    }

    /**
     * 上传本地文件至OSS
     *
     * @param file 文件
     * @param key  唯一key（在oss中的文件名字）
     */
    public void upload(File file, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传内容到指定的存储空间（bucketName）并保存为指定的文件名称（key）。
            // String content = "Hello OSS";
            // ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            ossClient.putObject(bucketName, key, new FileInputStream(file));
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传网络文件至OSS
     *
     * @param url 文件url，如：http://www.baidu.com/xxx.jpg
     * @param key 唯一key（在oss中的文件名字）
     */
    public void uploadNetwork(String url, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传网络流。
            InputStream inputStream = new URL(url).openStream();
            ossClient.putObject(bucketName, key, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传网络文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 删除OSS中的文件
     *
     * @param key 唯一key（在oss中的文件名字）
     */
    public void delete(String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 删除文件。
            ossClient.deleteObject(bucketName, key);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("删除文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

}